const ncname = `[a-zA-Z_][\\-\\.0-9_a-zA-Z]*`
const qnameCapture = `((?:${ncname}\\:)?${ncname})`
const startTagOpen = new RegExp(`^<${qnameCapture}`)
const startTagClose = /^\s*(\/?)>/
const attribute = /^\s*([^\s"'<>\/=]+)(?:\s*(=)\s*(?:"([^"]*)"+|'([^']*)'+|([^\s"'=<>`]+)))?/
const endTag = new RegExp(`^<\\/${qnameCapture}[^>]*>`)
export function parseHTML(html) {
    let stack = []
    let root = null
    function createAstElement(tag, attrs, type, parent) {
        return {
            tag,
            type: 1,
            children: [],
            parent,
            attrs
        }
    }
    function text(char) {
        const parent = stack[stack.length-1]
        if(parent) {
            parent.children.push({
                text:char,
                type:2
            })
        }
    }
    function start(name, attrs) {
        const parent = stack[stack.length-1]
        const element =createAstElement(name, attrs, parent)
        if(!root) {
            root = element
        }
        if(parent) {
            parent.children.push(element)
        }

        stack.push(element)
    }
    function end(endName) {
        const endTag = stack.pop()
        if(endTag.tag !== endName) {
            console.error(`${endTag.tag}error`)
        }
    }
    function advance(length) {
        html = html.substring(length)
    }
    function parseStartTag() {
        const start = html.match(startTagOpen)
        if (!start) return
        const match = {
            name: start[1],
            attr: []
        }
        advance(start[0].length)

        let end
        let attr
        while (!(end = html.match(startTagClose)) && (attr = html.match(attribute))) {
            match.attr.push({
                name: attr[1],
                value: attr[3] || attr[4] || attr[5]
            })
            advance(attr[0].length)
        }
        if (end) {
            advance(end[0].length)
        }
        return match
    }
    while (html) {
        let index = html.indexOf('<')

        if (index === 0) {
            //开始
            const startTagMatch = parseStartTag()
            if (startTagMatch) {
                start(startTagMatch.name, startTagMatch.attr)
                continue
            }
            const endTagMatch = html.match(endTag)
            if (endTagMatch) {
                end(endTagMatch[1])
                advance(endTagMatch[0].length)
            }
        }

        if (index > 0) {
            const char = html.slice(0, index)
            text(char)
            advance(char.length)

            //文本
        }
    }
    return root
}
